home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / MPW_TOOL / TOOLS / TOOLS_WI / ICON_8 / ICONT_FO / LMEM.C < prev    next >
Text File  |  1990-03-02  |  13KB  |  569 lines

  1. /*
  2.  * lmem.c -- memory initialization and allocation; also parses arguments.
  3.  */
  4.  
  5. #include "::h:config.h"
  6. #include "tproto.h"
  7. #include "globals.h"
  8. #include "link.h"
  9. #include "general.h"
  10.  
  11. /*
  12.  * The following code is operating-system dependent [@lmem.01].  It includes
  13.  *  files that are system dependent.
  14.  */
  15.  
  16. #if PORT
  17.    /* nothing is needed */
  18. Deliberate Syntax Error
  19. #endif                    /* PORT */
  20.  
  21. #if AMIGA || ATARI_ST || HIGHC_386 || MACINTOSH || VMS
  22.    /* nothing is needed */
  23. #endif                    /* AMIGA || ATARI_AT || HIGHC_386 ... */
  24.  
  25. #if MSDOS
  26. #if MICROSOFT
  27. #include <sys/types.h>
  28. #include <sys/stat.h>
  29. #endif                    /* MICROSOFT */
  30. #if TURBO
  31. #include <sys/stat.h>
  32. #endif                    /* TURBO */
  33. #endif                    /* MSDOS */
  34.  
  35. #if MVS || VM
  36. #include <file.h>
  37. #endif                    /* MVS || VM */
  38.  
  39. #if OS2
  40. #if MICROSOFT
  41. #include <sys/types.h>
  42. #include <sys/stat.h>
  43. #endif                    /* MICROSOFT */
  44. #endif                    /* OS2 */
  45.  
  46. #if UNIX
  47. #ifndef ATT3B
  48. #include <sys/types.h>
  49. #include <sys/stat.h>
  50. #endif                    /* ATT3B */
  51. #endif                    /* UNIX */
  52.  
  53. /*
  54.  * End of operating-system specific code.
  55.  */
  56.  
  57. /*
  58.  * Prototypes.
  59.  */
  60.  
  61. hidden struct    lfile *alclfile    Params((char *name));
  62. hidden int    canread        Params((char *file));
  63. hidden novalue    freelfile    Params((struct lfile *p));
  64. hidden int    trypath        Params((char *name,char *file));
  65.  
  66. /*
  67.  * Memory initialization
  68.  */
  69.  
  70. struct gentry **lghash;        /* hash area for global table */
  71. struct ientry **lihash;        /* hash area for identifier table */
  72. struct fentry **lfhash;        /* hash area for field table */
  73.  
  74. struct lentry *lltable;        /* local table */
  75. struct gentry *lgtable;        /* global table */
  76. struct centry *lctable;        /* constant table */
  77. struct ientry *litable;        /* identifier table */
  78. struct fentry *lftable;        /* field table headers */
  79. struct rentry *lrtable;        /* field table record lists */
  80. struct ipc_fname *fnmtbl;    /* table associating ipc with file name */
  81. struct ipc_line *lntable;    /* table associating ipc with line number */
  82.  
  83. char *lsspace;            /* string space */
  84. word *labels;            /* label table */
  85. char *codeb;            /* generated code space */
  86.  
  87. struct gentry *lgfree;        /* free pointer for global table */
  88. struct ientry *lifree;        /* free pointer for identifier table */
  89. struct fentry *lffree;        /* free pointer for field table headers */
  90. struct rentry *lrfree;        /* free pointer for field table record lists */
  91. struct ipc_fname *fnmfree;    /* free pointer for ipc/file name table */
  92. struct ipc_line *lnfree;    /* free pointer for ipc/line number table */
  93. char *lsfree;            /* free pointer for string space */
  94. char *codep;            /* free pointer for code space */
  95.  
  96. char *lsend;            /* pointer to end of string space */
  97.  
  98. static char *ipath;        /* path for iconx */
  99.  
  100. #ifdef MultipleRuns
  101. extern word pc;
  102. extern int fatals;
  103. extern int nlflag;
  104. extern int lstatics;
  105. extern int nfields;
  106. #endif                    /* MultipleRuns */
  107.  
  108. /*
  109.  * linit - scan the command line arguments and initialize data structures.
  110.  */
  111. novalue linit()
  112.    {
  113.    struct gentry **gp;
  114.    struct ientry **ip;
  115.    struct fentry **fp;
  116.  
  117.    llfiles = NULL;        /* Zero queue of files to link. */
  118.  
  119. #ifdef EnvVars
  120.    ipath = getenv("IPATH");
  121. #else                    /* EnvVars */
  122.    ipath = NULL;
  123. #endif                    /* EnvVars */
  124.  
  125.    if (ipath == NULL)
  126.  
  127. /*
  128.  * The following code is operating-system dependent [@lmem.02].  Set default for
  129.  *  IPATH.
  130.  */
  131.  
  132. #if PORT
  133.    /* something is needed */
  134. Deliberate Syntax Error
  135. #endif                    /* PORT */
  136.  
  137. #if AMIGA
  138.    /*
  139.     * There is no environment, so set ipath to the null string. The
  140.     *  current directory is searched anyway and there is no symbol
  141.     *  to force current path search.
  142.     */
  143.       ipath = "";
  144. #endif                    /* AMIGA */
  145.  
  146. #if ATARI_ST || UNIX
  147.       ipath = ".";
  148. #endif                    /* ATARI_ST || UNIX */
  149.  
  150. #if HIGHC_386 || MSDOS || OS2
  151.       ipath = ";";
  152. #endif                    /* HIGHC_386 || MSDOS || OS2 */
  153.  
  154. #if MACINTOSH
  155. #if MPW || LSC
  156.       ipath = ":";
  157. #endif                    /* MPW || LSC */
  158. #endif                    /* MACINTOSH */
  159.  
  160. #if MVS || VM
  161.       ipath = "";
  162. #endif                    /* MVS || VS */
  163.  
  164. #if VMS
  165.       ipath = "[]";
  166. #endif                    /* VMS */
  167.  
  168. /*
  169.  * End of operating-system specific code.
  170.  */
  171.  
  172.    /*
  173.     * Allocate the various data structures that are used by the linker.
  174.     */
  175.    lghash   = (struct gentry **) tcalloc(ghsize, sizeof(struct gentry *));
  176.    lihash   = (struct ientry **) tcalloc(ihsize, sizeof(struct ientry *));
  177.    lfhash   = (struct fentry **) tcalloc(fhsize, sizeof(struct fentry *));
  178.  
  179.    lltable  = (struct lentry *) tcalloc(lsize, sizeof(struct lentry));
  180.    lctable  = (struct centry *) tcalloc(csize, sizeof(struct centry));
  181.  
  182.    lffree = lftable  = (struct fentry *) tcalloc(fsize, sizeof(struct fentry));
  183.    lgfree = lgtable  = (struct gentry *) tcalloc(gsize, sizeof(struct gentry));
  184.    lifree = litable  = (struct ientry *) tcalloc(isize, sizeof(struct ientry ));
  185.    lnfree = lntable  = (struct ipc_line*)tcalloc(nsize,sizeof(struct ipc_line));
  186.    lrfree = lrtable  = (struct rentry *) tcalloc(rsize, sizeof(struct rentry));
  187.  
  188.    lsfree = lsspace = (char *) tcalloc(stsize, sizeof(char));
  189.    lsend = lsspace + stsize - 1;
  190.  
  191.    fnmtbl = (struct ipc_fname *) tcalloc(fnmsize, sizeof(struct ipc_fname));
  192.    fnmfree = fnmtbl;
  193.  
  194.    labels  = (word *) tcalloc(maxlabels, sizeof(word));
  195.    codep = codeb = (char *) tcalloc(maxcode, 1);
  196.  
  197.    /*
  198.     * Zero out the hash tables.
  199.     */
  200.    for (gp = lghash; gp < &lghash[ghsize]; gp++)
  201.       *gp = NULL;
  202.    for (ip = lihash; ip < &lihash[ihsize]; ip++)
  203.       *ip = NULL;
  204.    for (fp = lfhash; fp < &lfhash[fhsize]; fp++)
  205.       *fp = NULL;
  206.  
  207. #ifdef MultipleRuns
  208.  
  209.    /*
  210.     * Initializations required for repeated program runs.
  211.     */
  212.  
  213.    pc = 0;                /* In lcode.c    */
  214.    nrecords = 0;            /* In lglob.c    */
  215.  
  216. #ifdef EvalTrace
  217.    colmno = 0;                /* In link.c    */
  218. #endif                    /* EvalTrace */
  219.  
  220.    lineno = 0;                /* In link.c    */
  221.    fatals = 0;                /* In link.c    */
  222.    nlflag = 0;                /* In llex.c    */
  223.    lstatics = 0;            /* In lsym.c    */
  224.    nfields = 0;                /* In lsym.c    */
  225. #endif                    /* MultipleRuns */
  226.  
  227.    /*
  228.     * Install "main" as a global variable in order to insure that it
  229.     *  is the first global variable.  iconx/start.s depends on main
  230.     *  being global number 0.
  231.     */
  232.    putglobal(instid("main"), F_Global, 0, 0);
  233.    }
  234.  
  235. #ifdef DeBugLinker
  236. /*
  237.  * dumplfiles - print the list of files to link.  Used for debugging only.
  238.  */
  239.  
  240. novalue dumplfiles()
  241.    {
  242.    struct lfile *p,*lfls;
  243.  
  244.    fprintf(stderr,"lfiles:\n");
  245.    lfls = llfiles;
  246.    while (p = getlfile(&lfls))
  247.        fprintf("stderr,'%s'\n",p->lf_name);
  248.    fflush(stderr);
  249.    }
  250. #endif                    /* DeBugLinker */
  251.  
  252. /*
  253.  * alsolink - create an lfile structure for the named file and add it to the
  254.  *  end of the list of files (llfiles) to generate link instructions for.
  255.  */
  256. static char *pptr;
  257. novalue alsolink(name)
  258. char *name;
  259.    {
  260.    struct lfile *nlf, *p;
  261.    char file[256], ok;
  262.  
  263.    ok = 0;
  264.    if (canread(name)) {
  265.       ok++;
  266.       strcpy(file, name);
  267.       }
  268.    else {
  269.       /*
  270.        * Can't find name in current directory so try paths in
  271.        *   ipath if there are any. (ipath cannot override the
  272.        *   current directory first strategy so there is probably
  273.        *   no reason to initialize ipath to the various current
  274.        *   directory markers as is done above, since this will
  275.        *   only result in a duplicate failed search. Note that
  276.        *   the access test which is done above in some systems
  277.        *   will have already caused ilink to exit if name is
  278.        *   not found in the current directory anyway so ipath
  279.        *   was never able to search other paths first in any case.)
  280.        */
  281.  
  282.  
  283.       pptr = ipath;
  284.  
  285.       while (trypath(name, file)) {
  286.          if (canread(file)) {
  287.             ok++;
  288.             break;
  289.             }
  290.          }
  291.       }
  292.  
  293.    if (!ok)
  294.      quitf("cannot resolve reference to file '%s'",name);
  295.  
  296.    nlf = alclfile(file);
  297.    if (llfiles == NULL) {
  298.       llfiles = nlf;
  299.       }
  300.    else {
  301.       p = llfiles;
  302.       while (p->lf_link != NULL) {
  303.         if (strcmp(p->lf_name,file) == 0)
  304.            return;
  305.         p = p->lf_link;
  306.         }
  307.       if (strcmp(p->lf_name,file) == 0)
  308.         return;
  309.       p->lf_link = nlf;
  310.       }
  311.    }
  312.  
  313. /*
  314.  * getlfile - return a pointer (p) to the lfile structure pointed at by lptr
  315.  *  and move lptr to the lfile structure that p points at.  That is, getlfile
  316.  *  returns a pointer to the current (wrt. lptr) lfile and advances lptr.
  317.  */
  318. struct lfile *getlfile(lptr)
  319. struct lfile **lptr;
  320.    {
  321.    struct lfile *p;
  322.  
  323.    if (*lptr == NULL)
  324.       return (struct lfile *)NULL;
  325.    else {
  326.       p = *lptr;
  327.       *lptr = p->lf_link;
  328.       return p;
  329.       }
  330.    }
  331.  
  332. /*
  333.  * canread - see if file can be read and be sure that it's just an
  334.  *  ordinary file.
  335.  */
  336. static int canread(file)
  337. char *file;
  338.    {
  339.  
  340. /*
  341.  * The following code is operating-system dependent [@lmem.03]. Check to see if
  342.  *  .u1 file can be read.
  343.  */
  344.  
  345. #if PORT
  346.    /* something is needed */
  347. Deliberate Syntax Error
  348. #endif                    /* PORT */
  349.  
  350. #if AMIGA
  351.    char lclname[MaxFileName];
  352.    if (access(makename(lclname,TargetDir,file,U1Suffix),4) == 0)
  353.       if (getfa(lclname) == -1)
  354.          return 1;
  355. #endif                    /* AMIGA */
  356.  
  357. #if ATARI_ST || HIGHC_386
  358.    {
  359.    FILE *f;
  360.    char lclname[MaxFileName];
  361.    if ((f = fopen(makename(lclname,TargetDir,file,U1Suffix), "r")) == NULL)
  362.       return 0;
  363.    else {
  364.       fclose(f);
  365.       return 1;
  366.       }
  367.    }
  368. #endif                    /* ATARI_ST || HIGHC_386 */
  369.  
  370. #if MACINTOSH
  371. #if MPW || LSC
  372.    {
  373.    FILE *f;
  374.    if ((f = fopen(file,"r")) != NULL) {
  375.       fclose(f);
  376.       return 1;
  377.       }
  378.    }
  379. #endif                    /* MPW || LSC */
  380. #endif                    /* MACINTOSH */
  381.  
  382. #if MSDOS
  383. #if MICROSOFT || TURBO
  384.    struct stat statb;
  385.    if (access(file,4) == 0) {
  386.       stat(file,&statb);
  387.       if (statb.st_mode & S_IFREG)
  388.          return 1;
  389.       }
  390. #else                    /* MICROSOFT || TURBO */
  391.    char lclname[MaxFileName];
  392.    if (access( makename(lclname,TargetDir,file,U1Suffix), 4 ) == 0 )
  393.       return 1;
  394. #endif                    /* MICROSOFT || TURBO */
  395. #endif                    /* MSDOS */
  396.  
  397. #if MVS || VM
  398.    FILE *f;            /* can't use access because it will */
  399.                 /* accept LRECL, etc. */
  400.  
  401.    if ((f = fopen(file,"r")) != NULL {
  402.       fclose(f);
  403.       return 1;
  404.       }
  405. #endif                    /* MVS || VM */
  406.  
  407. #if OS2
  408. #if MICROSOFT
  409.    struct stat statb;
  410.    if (access(file,4) == 0) {
  411.       stat(file,&statb);
  412.       if (statb.st_mode & S_IFREG)
  413.          return 1;
  414.       }
  415. #endif                    /* MICROSOFT || TURBO */
  416. #endif                    /* OS2 */
  417.  
  418. #if UNIX
  419.    struct stat statb;
  420.    if (access(file,4) == 0) {
  421.       stat(file,&statb);
  422.       if (statb.st_mode & S_IFREG)
  423.          return 1;
  424.       }
  425. #endif                    /* UNIX */
  426.  
  427. #if VMS
  428.    char lclname[MaxFileName];
  429.    if (access(makename(lclname,TargetDir,file,U1Suffix),4) == 0)
  430.       return 1;
  431. #endif                    /* VMS */
  432.  
  433. /*
  434.  * End of operating-system specific code.
  435.  */
  436.  
  437.    return 0;
  438.    }
  439.  
  440.  
  441. /*
  442.  * trypath - form a file name in file by concatenating name onto the
  443.  *  next path element.
  444.  */
  445. static int trypath(name,file)
  446. char *name, *file;
  447.    {
  448.    char c;
  449.  
  450.    while (*pptr == ' ')
  451.       pptr++;
  452.    if (!*pptr)
  453.       return 0;
  454.    do {
  455.       c = (*file++ = *pptr++);
  456.       }
  457.       while (c != ' ' && c);
  458.    pptr--;
  459.    file--;
  460.  
  461. /*
  462.  * The following code is operating-system dependent [@lmem.04].  Append path
  463.  *  character.
  464.  */
  465.  
  466. #if PORT
  467.    /* nothing is needed */
  468. Deliberate Syntax Error
  469. #endif                    /* PORT */
  470.  
  471. #if AMIGA
  472.    file--;
  473.    switch (*file) {
  474.  
  475.       case ':':
  476.       case '/':
  477.                  file++;
  478.                  break;       /* add nothing, delimiter already there */
  479.       default:
  480.                  *file++ = '/';
  481.       }
  482. #endif                    /* AMIGA */
  483.  
  484. #if ATARI_ST || MACINTOSH || MVS || VM || VMS
  485.    /* nothing is needed */
  486. #endif                    /* ATARI_ST || MACINTOSH */
  487.  
  488. #if HIGHC_386
  489.    *file++ = '\\';
  490. #endif                    /* HIGHC_386 */
  491.  
  492. #if UNIX || MSDOS || OS2
  493.    *file++ = '/';            /* should check for delimiter */
  494. #endif                    /* UNIX || MSDOS || OS2 */
  495.  
  496. /*
  497.  * End of operating-system specific code.
  498.  */
  499.  
  500.    while (*file++ = *name++);
  501.    *file = 0;
  502.    return 1;
  503.    }
  504.  
  505. /*
  506.  * alclfile - allocate an lfile structure for the named file, fill
  507.  *  in the name and return a pointer to it.
  508.  */
  509. static struct lfile *alclfile(name)
  510. char *name;
  511.    {
  512.    struct lfile *p;
  513.  
  514.    p = (struct lfile *) alloc(sizeof(struct lfile));
  515.    p->lf_link = NULL;
  516.    p->lf_name = salloc(name);
  517.    return p;
  518.    }
  519.  
  520. #ifdef MultipleRuns
  521. /*
  522.  * freelfile - free memory of an lfile structure.
  523.  */
  524. static novalue freelfile(p)
  525. struct lfile *p;
  526.    {
  527.    free(p->lf_name);
  528.    free((char *) p);
  529.    }
  530. #endif                        /* MultipleRuns */
  531.  
  532. /*
  533.  * lmfree - free memory used by the linker
  534.  */
  535. novalue lmfree()
  536.    {
  537.    struct lfile *lf, *nlf;
  538.  
  539.    free((char *) lghash);   lghash = NULL;
  540.    free((char *) lihash);   lihash = NULL;
  541.    free((char *) lfhash);   lfhash = NULL;
  542.    free((char *) lltable);   lltable = NULL;
  543.    free((char *) lctable);   lctable = NULL;
  544.    free((char *) lftable);   lftable = NULL;
  545.    free((char *) lgtable);   lgtable = NULL;
  546.    free((char *) litable);   litable = NULL;
  547.    free((char *) lntable);   lntable = NULL;
  548.    free((char *) lrtable);   lrtable = NULL;
  549.    free((char *) lsspace);   lsspace = NULL;
  550.    free((char *) fnmtbl);   fnmtbl = NULL;
  551.    free((char *) labels);   labels = NULL;
  552.    free((char *) codep);   codep = NULL;
  553.  
  554. #ifdef MultipleRuns
  555.    for (lf = llfiles; lf != NULL; lf = nlf) {
  556.       nlf = lf->lf_link;
  557.       freelfile(lf);
  558.       }
  559.    llfiles = NULL;
  560.  
  561. #if MACINTOSH
  562. #if MPW
  563. /* #pragma unused(nlf,lf) */
  564. #endif                    /* MPW */
  565. #endif                    /* MACINTOSH */
  566. #endif                    /* MultipleRuns */
  567.  
  568.    }
  569.